#include "Prerequis.h"

//#include <iomanip>
#include "FlotMessage.h"

#include "Caracteristique.h"

#include <boost/assign/list_of.hpp>

using namespace std;
using namespace boost::assign;

/******************************************************************************
 *
 * Définition de la classe Prerequis
 *
 *****************************************************************************/

/** Constructeur par défaut.
 * Permet de construire un prérequis sur les traits, avec des bornes
 * inférieure et suppérieure.
 *
 * @param[in] trait numéro du trait (par défaut 0, càd Force).
 * @param[in] min valeur minimale (par défaut 3).
 * @param[in] max valeur maximale (par défaut 26, pour ne pas avoir de max).
 */
Prerequis::Prerequis( const unsigned& trait, const unsigned& min,
		      const unsigned& max )
  : TraitNbr( trait ), Min( min ), Max( max )
{}

/** Constructeur de copie
 * Permet de dupliquer proprement une instance de Prerequis.
 *
 * @param[in] preRequis instance à copier.
 */
Prerequis::Prerequis( const Prerequis& preRequis )
  : TraitNbr( preRequis.TraitNbr ), Min( preRequis.Min ), Max( preRequis.Max )
{}

/**
 * Destructeur, ne fait rien de spécial.
 */
Prerequis::~Prerequis()
{}

/**
 * Opérateur d'affectation, permet copier une instance de Prereqis.
 *
 * @param[in] preRequis instance à copier.
 *
 * @return une référence constance sur l'instance courante.
 */
const Prerequis& Prerequis::operator=( const Prerequis& preRequis )
{
  TraitNbr = preRequis.TraitNbr;
  Min   = preRequis.Min;
  Max   = preRequis.Max;

  return *this;
}

/**
 * Vérifie si les traits donnés sont correct compte tenu de l'instance
 * courante.
 *
 * @param[in] tab tableau des traits.
 *
 * @return StatusCode \e true si OK, \e false sinon. Dans ce dernier
 * cas, Valeur donne le trait qui empêche la création dans valeur(),
 * la borne dans valeur(1) et un message.
 */
StatusCode Prerequis::estOK( const vector< unsigned >& tab ) const
{
  vector< int > vec;
  if ( tab[ TraitNbr ] < Min )
    return StatusCode( false, vec = list_of( TraitNbr )( Min ), 0,
		       "Valeur insuffisante" );
  else if ( tab[ TraitNbr ] > Max ) 
    return StatusCode( false, vec = list_of( TraitNbr )( Max ), 0,
		       "Valeur trop grande" );
  else
    return StatusCode( true );
}

/**
 * Permet d'afficher simplement un prérequis dans un flot de sortie
 * quelconque. On utilise Caracteristique pour le nom du trait.
 *
 * @param[in] os référence sur le flot de sortie dans lequel on veut
 * écrire l'instance de Prerequis.
 * @param[in] preRequis instance que l'on veut écrire.
 *
 * @return une référence sur le flot de sortie utilisé.
 */
ostream& operator<<( ostream& os, const Prerequis& preRequis )
{
  Caracteristique trait( preRequis.TraitNbr );

  os << preRequis.Min << " < " /*<< setw(12)*/ << trait
     << " < " << preRequis.Max;

  return os;
}

/**
 * Permet d'afficher simplement un prérequis dans un flot de sortie
 * quelconque. On utilise Caracteristique pour le nom du trait.
 *
 * @param[in] os référence sur le flot de sortie dans lequel on veut
 * écrire l'instance de Prerequis.
 * @param[in] preRequis instance que l'on veut écrire.
 *
 * @return une référence sur le flot de sortie utilisé.
 */
FlotMessage& operator<<( FlotMessage& flot, const Prerequis& preRequis )
{
  Caracteristique trait( preRequis.TraitNbr );

  flot << preRequis.Min << " < " << trait << " < " << preRequis.Max;

  return flot;
}
